package com.hbk.service.impl;

import java.util.*;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hbk.dao.*;
import com.hbk.pojos.*;
import com.hbk.dto.*;
import com.hbk.service.*;
import com.hbk.utils.sql.*;

@Service
public class ${clazzAlias}ServiceImpl implements I${clazzAlias}Service {
    
	@Resource
	private IBaseDao baseDao;
	
	<#list methods as method>
	@Transactional<#if (method.method=='Get')>(readOnly=true)</#if>
	@Override
	public ${method.result} ${method.name}(${method.paramsStr}){
		<#if (method.algorithm=='simple-save')>
		<#--  -->
		<#--  -->
		baseDao.save(${method.params[0].var});
		<#--  -->
		<#--  -->
		<#elseif (method.algorithm=='simple-update')>
		<#--  -->
		<#--  -->
		baseDao.update(${method.params[0].var});
		<#--  -->
		<#--  -->
		<#elseif (method.algorithm=='simple-delete')>
		<#--  -->
		<#--  -->
		baseDao.delete(baseDao.get(${clazz}.class,${method.params[0].var}));
		<#elseif (method.algorithm=='simple-get')>
		<#--  -->
		<#--  -->
		return (${method.result})baseDao.get(${method.result}.class,${method.params[0].var});
		<#--  -->
		<#--  -->
		<#elseif (method.algorithm=='map-get')>
		<#--  -->
		<#--  -->
		return baseDao.getUniqueMap("${method.sql}<#list method.queryCondition as field> and ${field.refColumn}=?${field_index}</#list>"<#list method.queryCondition as field>, ${field.var}</#list>);
		<#--  -->
		<#--  -->
		<#elseif (method.algorithm=='bean-get')>
		<#--  -->
		<#--  -->
		return (${method.result})baseDao.getUniqueBean(new ${method.result}(),"${method.sql}<#list method.queryCondition as field> and ${field.refColumn}=?${field_index}</#list>"<#list method.queryCondition as field>, ${field.var}</#list>);
		<#--  -->
		<#--  -->
		<#elseif (method.algorithm=='attribute-find')>
		<#--  -->
		<#--  -->
		LinkSql sql = new LinkSql("${method.sql}");<#list method.queryCondition as field><#if (field.type=='String')>
		sql.likeIfHasText("${field.refColumn}", <#if (field.dto)>${field.var}.get${field.name?cap_first}()<#else>${field.var}</#if>);<#else>
		sql.equalIfNotNull("${field.refColumn}", <#if (field.dto)>${field.var}.get${field.name?cap_first}()<#else>${field.var}</#if>);
		</#if>
		</#list>
		sql.orderDescBy("${method.order}");
		return baseDao.findMaps(sql.toString());
		<#--  -->
		<#--  -->
		<#elseif (method.algorithm=='attribute-tree')>
		<#--  -->
		<#--  -->
		LinkSql sql = new LinkSql("${getSql(method.columns)}");
		<#list getQueryCondition(method.params) as field><#if (field.type=='String')>
		sql.likeIfHasText("${field.refColumn}", <#if (field.dto)>${field.var}.get${field.name?cap_first}()<#else>${field.var}</#if>);<#else>
		sql.equalIfNotNull("${field.refColumn}", <#if (field.dto)>${field.var}.get${field.name?cap_first}()<#else>${field.var}</#if>);
		</#if>
		</#list>
		sql.orderDescBy("${getOrder(method.orders)}");
		List<Map<Object,Object>> list=baseDao.find(sql.toString());
		return TreeUtil.organize(list);
		<#--  -->
		<#--  -->
		<#elseif (method.algorithm=='page-query')>
		<#--  -->
		<#--  -->
		LinkSql sql = new LinkSql("${method.sql}");
		<#list method.queryCondition as field>
		<#if (field.type=='String')>
		sql.likeIfHasText("${field.refColumn}", <#if (field.dto)>${field.var}.get${field.name?cap_first}()<#else>${field.var}</#if>);
		<#else>
		sql.equalIfNotNull("${field.refColumn}", <#if (field.dto)>${field.var}.get${field.name?cap_first}()<#else>${field.var}</#if>);
		</#if></#list>
		sql.orderDescBy("${method.order}");
		return baseDao.queryByPage(sql.toString(), query.getStart(), query.getPageSize());
		<#--  -->
		<#--  -->
		<#elseif (method.algorithm=='attribute-save')>
		<#--  -->
		<#--  -->
		${clazz} entity=new ${clazz}();
		<#list getQueryCondition(method.params) as field>
		<#if field.name=='id'>
		<#elseif getFetch(field.ref)=='OneToMany'>
		<#elseif getFetch(field.ref)=='ManyToOne' && field.type=='Long'>
		if(${field.var}.get${field.name?cap_first}()!=null){
			entity.set${field.refName?cap_first}(new ${getRefType(field.ref)}(${field.var}.get${field.name?cap_first}()));
		}
		<#elseif getFetch(field.ref)=='ManyToOne' && field.type!='Long'>
		if(${field.var}.get${field.name?cap_first}()!=null&&${field.var}.get${field.name?cap_first}().getId()!=null){
			entity.set${field.name?cap_first}(new ${getRefType(field.ref)}(${field.var}.get${field.name?cap_first}().getId()));
		}
		<#else>
		entity.set${field.refName?cap_first}(${field.var}.get${field.name?cap_first}());
		</#if>
		</#list>
		baseDao.save(entity);
		<#--  -->
		<#--  -->
		<#elseif (method.algorithm=='attribute-update')>
		<#--  -->
		<#--  -->
		${clazz} db=(${clazz})baseDao.get(${clazz}.class,${method.params[0].var}.getId());
		<#list getQueryCondition(method.params) as field>
		<#if field.name=='id'>
		<#elseif getFetch(field.ref)=='OneToMany'>
		<#elseif getFetch(field.ref)=='ManyToOne'>
		if(${field.var}.get${field.name?cap_first}()!=null&&${field.var}.get${field.name?cap_first}().getId()!=null){
			db.set${field.name?cap_first}(new ${getRefType(field.ref)}(${field.var}.get${field.name?cap_first}().getId()));
		}
		<#else>
		db.set${field.refName?cap_first}(${field.var}.get${field.name?cap_first}());
		</#if>
		</#list>
		baseDao.update(db);
		<#--  -->
		<#--  -->
		<#elseif (method.algorithm=='attribute-if-update')>
		<#--  -->
		<#--  -->
		${clazz} db=baseDao.get(${clazz}.class,${method.params[0].var}.getId());
		<#list fields as field>
		<#if field.name=='id'>
		<#elseif field.fetch=='OneToMany'>
		<#elseif field.fetch=='ManyToOne'>
		if(${method.params[0].var}.get${field.name?cap_first}()!=null&&${method.params[0].var}.get${field.name?cap_first}().getId()!=null){
			db.set${field.name?cap_first}(${method.params[0].var}.get${field.name?cap_first}());
		}
		<#else>
		if(${method.params[0].var}.get${field.name?cap_first}()!=null){
			db.set${field.name?cap_first}(${method.params[0].var}.get${field.name?cap_first}());
		}
		</#if>
		</#list>
		baseDao.update(db);
		<#--  -->
		<#--  -->
		<#elseif (method.algorithm=='cascade-dto-update')>
		<#--  -->
		<#--  -->
		${clazz} db=baseDao.get(${clazz}.class,${method.params[0].var}.getId());
		<#list getQueryCondition(method.params[0].type) as field>
		<#if field.name=='id'>
		<#elseif getFetch(field.ref)=='OneToMany'>
		for(${stripClazz(field.type)} dtoItem:${method.params[0].var}.get${field.name?cap_first}()){
			if(dtoItem.getId()==null) {
				${stripClazz(getRefType(field.ref))} newl=new ${stripClazz(getRefType(field.ref))}();
				<#list getDto(stripClazz(field.type)).fields as dtofield>
				<#if dtofield.name=='id'>
				<#elseif getFetch(dtofield.ref)=='ManyToOne'>
				if(dtoItem.get${dtofield.name?cap_first}()!=null&&dtoItem.get${dtofield.name?cap_first}().getId()!=null){
					db.set${dtofield.refName?cap_first}(new ${getRefType(dtofield.ref)}(dtoItem.get${dtofield.name?cap_first}().getId()));
				}
				<#else>
				dbItem.set${dtofield.refName?cap_first}(dtoItem.get${dtofield.name?cap_first}());
				</#if>
				</#list>
				newl.set${clazz}(db);
				baseDao.save(newl);
			}
		}
		List<${stripClazz(getRefType(field.ref))}> remove=new ArrayList<${stripClazz(getRefType(field.ref))}>();
		for(${stripClazz(getRefType(field.ref))} dbItem:db.get${field.refName?cap_first}()){
			boolean exist=false;
			for(${stripClazz(field.type)} dtoItem:${method.params[0].var}.get${field.name?cap_first}()){
				if(dbItem.getId().equals(dbItem.getId())){
					exist=true;
					break;
				}
			}
			if(!exist) {
				remove.add(dbItem);
			}
		}
		for(${stripClazz(getRefType(field.ref))} dbItem:remove) {
			baseDao.delete(dbItem);
		}
		db.get${field.refName?cap_first}().removeAll(remove);
		for(${stripClazz(getRefType(field.ref))} dbItem:db.get${field.refName?cap_first}()){
			for(${stripClazz(field.type)} dtoItem:${method.params[0].var}.get${field.name?cap_first}()){
				if(dbItem.getId().equals(dbItem.getId())){
					<#list getQueryCondition(stripClazz(field.type)) as dtofield>
					<#if dtofield.name=='id'>
					<#elseif getFetch(dtofield.ref)=='ManyToOne'>
					if(dtoItem.get${dtofield.name?cap_first}()!=null&&dtoItem.get${dtofield.name?cap_first}().getId()!=null){
						db.set${dtofield.refName?cap_first}(new ${getRefType(dtofield.ref)}(dtoItem.get${dtofield.name?cap_first}().getId()));
					}
					<#else>
					dbItem.set${dtofield.refName?cap_first}(dtoItem.get${dtofield.name?cap_first}());
					</#if>
					</#list>
					baseDao.update(dbItem);
				}
			}
		}
		<#elseif getFetch(field.ref)=='ManyToOne'>
		if(${method.params[0].var}.get${field.name?cap_first}()!=null&&${method.params[0].var}.get${field.name?cap_first}().getId()!=null){
			db.set${field.name?cap_first}(new ${getRefType(field.ref)}(${method.params[0].var}.get${field.name?cap_first}().getId()));
		}
		<#else>
		db.set${field.refName?cap_first}(${method.params[0].var}.get${field.name?cap_first}());
		</#if>
		</#list>
		baseDao.update(db);
		<#--  -->
		<#--  -->
		<#elseif (method.algorithm=='gen-code')>
		<#--  -->
		<#--  -->
${getGenerateCode(method.name)}
		<#--  -->
		<#--  -->
		<#else>
		<#--  -->
		<#--  -->
		//TODO impl method here
		<#if (method.result=='void')><#else>
		return null;
		</#if>
		<#--  -->
		<#--  -->
		</#if>
	}
	
	</#list>

}